package UMC.Web;

import UMC.Data.Utility;

import java.io.*;
import java.net.JarURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class PackageParse {


    static void dealClass(Class klass) {
        WebRuntime.register(klass);
    }

    public static void scanRoot(String packName) {
        scanRoot(Thread.currentThread().getContextClassLoader(), packName);
    }

    public static void scanRoot(ClassLoader classLoader, String packName) {

        String packageName = "";
        if (!packName.contains(".java")) {
            packageName = packName.replace(".", "/");
        } else {
            int lastIndex = packName.lastIndexOf(".");
            int secandIndex = packName.substring(0, lastIndex).lastIndexOf(".");
            packName = packName.substring(0, secandIndex);
            packageName = packName.substring(0, secandIndex).replace(".", "/");
        }
        try {
            Enumeration<URL> url = classLoader.getResources(packageName);
            while (url.hasMoreElements()) {
                URL ur = url.nextElement();
                String type = ur.getProtocol();
                if (type.equals("jar")) {
                    dealJar(ur, packName);
                } else if (type.equals("file")) {
                    File file = new File(ur.toURI());
                    if (file.isDirectory()) {
                        dealFiles(packName, file);
                    } else if (file.getName().contains(".class")) {
                        deaJavaFile(file, packName);
                    }
                }
            }
        } catch (IOException | URISyntaxException e) {
            e.printStackTrace();
        }
    }

    private static void dealFiles(String packageName, File file) {
        if (file.exists()) {
            File[] files = file.listFiles();
            for (File child : files) {
                if (child.isDirectory()) {

                    if (Utility.isEmpty(packageName)) {
                        dealFiles(child.getName(), child);
                    } else {
                        dealFiles(packageName + "." + child.getName(), child);
                    }
                } else if (child.getName().contains(".class")) {
                    deaJavaFile(child, packageName);
                }
            }
        }

    }


    private static void deaJavaFile(File file, String packageName) {

        int index = file.getName().lastIndexOf(".class");
        String filename = file.getName().substring(0, index);
        try {
            if (Utility.isEmpty(packageName)) {
                dealClass(Class.forName(filename));

            } else {
                dealClass(Class.forName(packageName + "." + filename));
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void dealJar(URL url, String packName) {
        JarURLConnection jarURLConnection;
        try {
            jarURLConnection = (JarURLConnection) url.openConnection();
            JarFile jarFile = jarURLConnection.getJarFile();
            Enumeration<JarEntry> jarEntries = jarFile.entries();
            while (jarEntries.hasMoreElements()) {
                JarEntry jar = jarEntries.nextElement();
                if (jar.isDirectory() || !jar.getName().endsWith(".class")) {
                    continue;
                }
                String jarName = jar.getName();
                int dotIndex = jarName.indexOf(".class");
                String className = jarName.substring(0, dotIndex).replace("/", ".");
                if (Utility.isEmpty(packName) || className.startsWith(packName)) {
                    Class klass = Class.forName(className);
                    dealClass(klass);
                }
            }

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}